module adder_64bits(
    input wire [63:0] a, //加数
    input wire [63:0] b, //加数
    input wire cin,
    output wire [63:0] result, //加法结果
    output wire cout, 
    output wire over
);
    wire [3:0] G_mid; 
    wire [3:0] P_mid;
    wire [4:0] C_mid;
    adder_16bits add16_1(.a(a[15:0]),  .b(b[15:0]),  .cin(C_mid[0]), .result(result[15:0]),  .cout(C_mid[1]), .P_mid(P_mid[0]), .G_mid(G_mid[0]));
    adder_16bits add16_2(.a(a[31:16]), .b(b[31:16]), .cin(C_mid[1]), .result(result[31:16]), .cout(C_mid[2]), .P_mid(P_mid[1]), .G_mid(G_mid[1]));
    adder_16bits add16_3(.a(a[47:32]), .b(b[47:32]), .cin(C_mid[2]), .result(result[47:32]), .cout(C_mid[3]), .P_mid(P_mid[2]), .G_mid(G_mid[2]));
    adder_16bits add16_4(.a(a[63:48]), .b(b[63:48]), .cin(C_mid[3]), .result(result[63:48]), .cout(C_mid[4]), .P_mid(P_mid[3]), .G_mid(G_mid[3]));

    assign C_mid[0] = cin;
    assign C_mid[1] = G_mid[0] | (P_mid[0]&C_mid[0]);
    assign C_mid[2] = G_mid[1] | (P_mid[1]&G_mid[0]) | (P_mid[1]&P_mid[0]&C_mid[0]);
    assign C_mid[3] = G_mid[2] | (P_mid[2]&G_mid[1]) | (P_mid[2]&P_mid[1]&G_mid[0]) | (P_mid[2]&P_mid[1]&P_mid[0]&C_mid[0]);
    assign C_mid[4] = G_mid[3] | (P_mid[3]&G_mid[2]) | (P_mid[3]&P_mid[2]&G_mid[1]) | (P_mid[3]&P_mid[2]&P_mid[1]&G_mid[0]) | (P_mid[3]&P_mid[2]&P_mid[1]&P_mid[0]&C_mid[0]);

    assign cout = C_mid[4];
    assign over = C_mid[2] ^ C_mid[3];
endmodule


module adder_16bits (
    input wire [15:0] a,        //加数
    input wire [15:0] b,        //被加数
    input wire cin,             //块间进位
    output wire [15:0] result,  //加法结果
    output wire over,           //加法溢出
    output wire cout,            //进位输出
    output wire P_mid,
    output wire G_mid
);
//先行进位
 wire [3:0] G;             //进位生成因子
 wire [3:0] P;             //进位传递因子
 wire [4:0] c_mid;         //中间进位
 
adder_4bits add4_1(.a(a[3:0]), .b(b[3:0]), .cin(c_mid[0]), .over(c_mid[1]), .result(result[3:0]), .G(G[0]), .P(P[0]));
adder_4bits add4_2(.a(a[7:4]), .b(b[7:4]), .cin(c_mid[1]), .over(c_mid[2]), .result(result[7:4]), .G(G[1]), .P(P[1]));
adder_4bits add4_3(.a(a[11:8]), .b(b[11:8]), .cin(c_mid[2]), .over(c_mid[3]), .result(result[11:8]), .G(G[2]), .P(P[2]));
adder_4bits add4_4(.a(a[15:12]), .b(b[15:12]), .cin(c_mid[3]), .over(c_mid[4]), .result(result[15:12]), .G(G[3]), .P(P[3]));

//上层一块先行进位逻辑
assign c_mid[0] = cin;
assign c_mid[1] = G[0] | (P[0]&c_mid[0]);
assign c_mid[2] = G[1] | (P[1]&G[0]) | (P[1]&P[0]&c_mid[0]);
assign c_mid[3] = G[2] | (P[2]&G[1]) | (P[2]&P[1]&G[0]) | (P[2]&P[1]&P[0]&c_mid[0]);
assign c_mid[4] = G[3] | (P[3]&G[2]) | (P[3]&P[2]&G[1]) | (P[3]&P[2]&P[1]&G[0]) | (P[3]&P[2]&P[1]&P[0]&c_mid[0]);

assign cout = c_mid[4];
assign over = c_mid[3] ^ c_mid[2];

assign P_mid = P[0] & P[1] & P[2] & P[3];
assign G_mid = G[3] | (P[3]&G[2]) | (P[3]&P[2]&G[1]) | (P[3]&P[2]&P[1]&G[0]);

endmodule


module adder_4bits (
    input wire [3:0] a,        //加数
    input wire [3:0] b,        //被加数
    input wire cin,            //进位
    output wire over,          //输出进位
    output wire [3:0] result,   //加法结果
    output wire G,             //进位生成因子
    output wire P              //进位传递因子
);
    //先行进位加法器思想
    wire [3:0] p;//进位传递因子
    wire [3:0] g;//进位生成因子
    wire [4:0] c;//进位输入

    assign g = a & b;
    assign p = a | b;

    assign c[0] = cin;
    assign c[1] = g[0] | (p[0]&c[0]);
    assign c[2] = g[1] | (p[1]&g[0]) | (p[1]&p[0]&c[0]);
    assign c[3] = g[2] | (p[2]&g[1]) | (p[2]&p[1]&g[0]) | (p[2]&p[1]&p[0]&c[0]);
    assign c[4] = g[3] | (p[3]&g[2]) | (p[3]&p[2]&g[1]) | (p[3]&p[2]&p[1]&g[0]) | (p[3]&p[2]&p[1]&p[0]&c[0]);

    assign result = a ^ b ^ c;

    assign over = c[4];

    assign P = p[0] & p[1] & p[2] & p[3];
    assign G = g[3] | (p[3]&g[2]) | (p[3]&p[2]&g[1]) | (p[3]&p[2]&p[1]&g[0]);
endmodule
